<!--
    /**
     * 树形下拉选择组件，下拉框展示树形结构，提供选择某节点功能，方便其他模块调用
     * 调用示例：
     * <pf-tree-select :height="400" // 下拉框中树形高度
     *              :width="200" // 下拉框中树形宽度
     *              size="small"  // 输入框的尺寸: medium/small/mini
     *              :data="data" // 树结构的数据
     *              :defaultProps="defaultProps" // 树结构的props
     *              multiple   // 多选
     *              clearable   // 可清空选择
     *              collapseTags   // 多选时将选中值按文字的形式展示
     *              checkStrictly // 多选时，严格遵循父子不互相关联
     *              :nodeKey="nodeKey"   // 绑定nodeKey，默认绑定'id'
     *              :checkedKeys="defaultCheckedKeys"  // 传递默认选中的节点key组成的数组
     *              @popoverHide="popoverHide"> // 事件有两个参数：第一个是所有选中的节点ID，第二个是所有选中的节点数据
     *              </pf-tree-select>
     */
-->
<template>
  <div class="pfTreeSelect">
    <div class="mask" v-show="isShowSelect" @click="isShowSelect = !isShowSelect"></div>
    <input type="hidden" :value="newValue" style="width:100%" />
    <el-popover placement="bottom-start" :width="width" trigger="manual"
                v-model="isShowSelect" @hide="popoverHide">
			<el-input placeholder="输入搜索关键字" v-model="filterText" v-if="isFilter" :validate-event="false"></el-input>
      <el-tree class="common-tree" :style="style" ref="tree" :data="data" :props="defaultProps"
               :show-checkbox="multiple"
               :node-key="nodeKey"
               :check-strictly="checkStrictly"
               :default-expand-all="false"
               :expand-on-click-node="false"
               :check-on-click-node="multiple"
               :default-expanded-keys="defalutExpanded"
               :highlight-current="true"
               :lazy="lazy"
               :load="loadNode"
                :filter-node-method="filterNode"
               @node-click="handleNodeClick"
               @check-change="handleCheckChange"></el-tree>
      <el-select :style="selectStyle" slot="reference" ref="select" :size="size"
                 v-model="selectedData"
                 :multiple="multiple"
                 :clearable="clearable"
                 :collapse-tags="collapseTags"
                 @click.native="isShowSelect = !isShowSelect"
                 @remove-tag="removeSelectedNodes"
                 @clear="removeSelectedNode"
                 @change="changeSelectedNodes"
                 class="tree-select">
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
      </el-select>
    </el-popover>
  </div>
</template>
<style lang="less">
.el-tree-node__label {
    font-size: 12px;
}
.pfTreeSelect .el-select {
    width: 100%;
}
.el-input--small .el-input__icon.el-icon-circle-close{
  display: none;
}
</style>
<script>
export default {
  name: 'pf-tree-select',
  props: {
    // 树结构数据
    data: {
      type: Array,
      default () {
        return [];
      }
    },
    defaultProps: {
      type: Object,
      default () {
        return {};
      }
    },
    defalutExpanded: {
      type: Array,
      default () {
        return [];
      }
    },
		noChoice:{
      type: Object,
      default () {
        return {};
      }
		},
    // 配置是否可多选
    multiple: {
      type: Boolean,
      default () {
        return false;
      }
    },
    // 配置是否可清空选择
    clearable: {
      type: Boolean,
      default () {
        return false;
      }
    },
    // 配置多选时是否将选中值按文字的形式展示
    collapseTags: {
      type: Boolean,
      default () {
        return false;
      }
    },
    nodeKey: {
      type: String,
      default () {
        return 'id';
      }
    },
    // 显示复选框情况下，是否严格遵循父子不互相关联
    checkStrictly: {
      type: Boolean,
      default () {
        return false;
      }
    },
    // 默认选中的节点key数组
    checkedKeys: {
      type: Array,
      default () {
        return [];
      }
    },
    size: {
      type: String,
      default () {
        return 'small';
      }
    },
    width: {
      type: String,
      default () {
        return '250px';
      }
    },
    height: {type: String,default () {return '300px';}},
    maxHeight: {type: String,default () {return '300px';}},
    lazy:{type:Boolean, default:false},
		loadNode:{type:Function, default:null},
		filterNode:{type:Function, default:null},
		// value: String|Object|Array,
		unableSelectData: Array,
		isFilter:{type:Boolean, default:false},
  },
  data () {
    return {
      isShowSelect: false, // 是否显示树状选择器
      options: [],
      selectedData: null, // 选中的节点
      style: 'width:' + this.width + ';' + 'height:' + this.height + ';max-height:' + this.maxHeight,
      selectStyle: 'width:' + (this.width + 24) + 'px;',
      checkedIds: [],
			checkedData: [],
			filterText:"",
    };
  },
  computed:{
    newValue: {
      get:function() {
        return this.value; 
      },
      set:function(value) {
        this.$emit('input', value)
      }
    },
    a:function(){
      return 0
    }
  },
  mounted () {
		this.initCheckedData();
  },
  created(){
  },
  methods: {
    // 单选时点击tree节点，设置select选项
    setSelectOption (node) {
      if(!node){
        return
			}
			let tmpMap = {};
      tmpMap.value = node.key;
			tmpMap.label = node.label;
      this.options = [];
			this.options.push(tmpMap);
			if(this.unableSelectData){
				if(this.unableSelectData[0] == node.data[this.unableSelectData[1]]){
					this.selectedData = this.unableSelectData[0]
				}
			}else{
        this.selectedData = node.key;
			}
    },
    // 单选，选中传进来的节点
    checkSelectedNode (checkedKeys) {
      var item = checkedKeys[0];
      this.$refs.tree.setCurrentKey(item);
			var node = this.$refs.tree.getNode(item);
      this.setSelectOption(node);
    },
    // 多选，勾选上传进来的节点
    checkSelectedNodes (checkedKeys) {
      this.$refs.tree.setCheckedKeys(checkedKeys);    
      // 蔡伟强，因为多选默认值显示不了 7月31
      if(checkedKeys[0]){
        this.selectedData = checkedKeys
        this.$emit('change', this.selectedData)
      } 
    },
    // 单选，清空选中
    clearSelectedNode () {     
      this.selectedData = '';
      this.$refs.tree.setCurrentKey(null);
    },
    // 多选，清空所有勾选
    clearSelectedNodes () {
      var checkedKeys = this.$refs.tree.getCheckedKeys(); // 所有被选中的节点的 key 所组成的数组数据
      for (let i = 0; i < checkedKeys.length; i++) {
        this.$refs.tree.setChecked(checkedKeys[i], false);
      }
    },
    initCheckedData () {
      if (this.multiple) {
        // 多选
        if (this.checkedKeys.length > 0) {
          this.checkSelectedNodes(this.checkedKeys);
        } else {
          this.$parent.$emit("el.form.blur");
          this.clearSelectedNodes();
        }
      } else {
        // 单选
        if (this.checkedKeys.length > 0) {
          this.options = [];
          this.options.push(this.checkedKeys[0]);
					this.selectedData = this.checkedKeys[0].value;
        } else {
          this.clearSelectedNode();
        }
      }
    },
    popoverHide () {
			this.filterText = ""
      if (this.multiple) {
        this.checkedIds = this.$refs.tree.getCheckedKeys(); // 所有被选中的节点的 key 所组成的数组数据
				this.checkedData = this.$refs.tree.getCheckedNodes(); // 所有被选中的节点所组成的数组数据
      } else {
        this.checkedIds = this.$refs.tree.getCurrentKey();
        this.checkedData = this.$refs.tree.getCurrentNode();
      }
      this.$emit('popoverHide', this.checkedIds, this.checkedData);
    },
    // 单选，节点被点击时的回调,返回被点击的节点数据
    handleNodeClick (data, node) {
      if (!this.multiple) {
        this.setSelectOption(node);
				this.isShowSelect = !this.isShowSelect
				/**
				 * 雷志逸修改
				 * 原本样子
        		this.$emit('change', this.selectedData)
				 */
				if(this.unableSelectData != undefined){
					this.$emit('change', data)
				}else{
					if(this.selectedData == undefined){
						this.$emit('change', data)
					}else{
						this.$emit('change', this.selectedData,data)
					}
				}
				this.newValue = data
      }
    },
    // 多选，节点勾选状态发生变化时的回调
    handleCheckChange () {
			var checkedKeys = []
			if(this.checkedKeys.length>0){
				for(let i of this.checkedKeys){
					checkedKeys.push(i)
				}
			}
			let currentData = this.$refs.tree.getCheckedKeys()
			for(let i in currentData){
				if(this.$refs.tree.getNode(currentData[i])){
					let nodes = this.$refs.tree.getNode(currentData[i]),state = false
					if(this.noChoice.attribute){
						if( nodes.data && nodes.data[this.noChoice.attribute.type] == this.noChoice.attribute.value){
							if(this.noChoice.attribute.otherValue.length>0){
								if(this.noChoice.attribute.otherValue.indexOf(nodes.data[this.noChoice.attribute.otherAttribute]) == -1) state = true
							}else{
								if(nodes.data[this.noChoice.attribute.otherAttribute] != this.noChoice.attribute.otherValue) state = true
							}
						}
					}
					if(state){
						this.$refs.tree.setChecked(nodes.data.value,false)
						this.$emit('noChoiceSelect');
						return false
					}
				}
			}
			checkedKeys = checkedKeys.concat(this.$refs.tree.getCheckedKeys()) // 所有被选中的节点的 key 所组成的数组数据
			for (let i = 0; i < checkedKeys.length; i++) {
				for (let j = i + 1; j < checkedKeys.length; j++) {
					if (checkedKeys[i] == checkedKeys[j]) {
						checkedKeys.splice(j, 1);
					}
				}
			}
			if(checkedKeys.indexOf("")!=-1){
				checkedKeys.splice(checkedKeys.indexOf(""),1)
			}
			// var checkedKeys = this.$refs.tree.getCheckedKeys(); // 所有被选中的节点的 key 所组成的数组数据
      this.options = checkedKeys.map((item) => {
				var node = {} // 所有被选中的节点对应的node
				// 需要手动修改this.defaultProps.state中的状态
				if(this.$refs.tree.getNode(item) == null && this.defaultProps.state!=undefined && !this.defaultProps.state){
					node.key = this.defaultProps.data.key
					node.label = this.defaultProps.data.text
				}else{
					if(this.$refs.tree.getNode(item)){
						node = this.$refs.tree.getNode(item)
					}else{
						node.key = item
						node.label = item
					}
				}
				let tmpMap = {};
				tmpMap.value = node.key;
				tmpMap.label = node.label;
				return tmpMap;
			});
			for (let i = 0; i < this.options.length; i++) {
				for (let j = i + 1; j < this.options.length; j++) {
					if (this.options[i].value == this.options[j].value) {
						this.options.splice(j, 1);
					}
				}
			}
      this.selectedData = this.options.map((item) => {
        return item.value;
			});
      this.$emit('change', this.selectedData);
    },
    // 多选,删除任一select选项的回调
    removeSelectedNodes (val) {
			// this.$refs.tree.setChecked(val, false);
			var node = this.$refs.tree.getNode(val);
      if (!this.checkStrictly && node.childNodes.length > 0) {
        this.treeToList(node).map(item => {
          if (item.childNodes.length <= 0) {
            this.$refs.tree.setChecked(item, false);
          }
        });
        this.handleCheckChange();
			}
			this.$emit('removeTags', val);
			this.$emit('change', this.selectedData);
    },
    treeToList (tree) {
      var queen = [];
      var out = [];
			queen = queen.concat(tree);
      while (queen.length) {
				var first = queen.shift();
        if (first.childNodes) {
          queen = queen.concat(first.childNodes);
        }
        out.push(first);
      }
      return out;
    },
    // 单选,清空select输入框的回调
    removeSelectedNode () {
      this.clearSelectedNode();
      this.$emit('change', this.selectedData);
    },
    // 选中的select选项改变的回调
    changeSelectedNodes (selectedData) {
      // 多选,清空select输入框时，清除树勾选
      if (this.multiple && selectedData.length <= 0) {
        this.clearSelectedNodes();
			}
      this.$emit('change', this.selectedData);
		},
  },
  watch: {
    isShowSelect () { // val
      // 隐藏select自带的下拉框
      this.$refs.select.blur();
    },
    checkedKeys (val) {
			if (!val) return;
      this.checkedKeys = val;
      this.initCheckedData();
		},
		filterText(val) {
			this.$refs.tree.filter(val);
    },
  }
};
</script>
 
<style scoped>
  .mask{
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    opacity: 0;
    z-index: 11;
  }
  .common-tree{
    overflow: auto;
  }
  .tree-select{
    z-index: 111;
  }
</style>